﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Projet_Synthese;

namespace Projet_Synthese
{
    public class Outils
    {
        public static Partie Load(String file,Texture2D[] texture,bool modeEdit=false)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(file);
            Partie partie = null;
            XmlNode nodePartie = doc.SelectNodes("Partie").Item(0);
            LoadParametre(nodePartie, out partie);
            List<Tangram> liste = partie.Tangrams;
            nodePartie = doc.SelectNodes("Partie").Item(0);
            foreach (XmlNode node in nodePartie.ChildNodes)
            {
                if (node.Name != "Tangram")
                    continue;
                Tangram tangram = new Tangram();
                Case [] cases = new Case[7];
                int i =0;
                foreach(XmlNode nForme in node.ChildNodes)
                {
                    FormeGeometrique forme = LoadFormeGeometrique(nForme, texture);
                    if(forme==null)
                    {
                        cases = null;
                        break;
                    }
                    cases[i] = new Case(forme);
                    i++;
                }
                if (cases != null)
                {
                    tangram.Nom = node.Attributes.GetNamedItem("Nom").Value;
                    tangram.Textures = texture;
                    if (modeEdit)
                        tangram.Cases = ToListe(cases);
                    else
                    {
                        tangram.FormeOrignes = cases;
                        tangram.Initialisation();
                    }
                    liste.Add(tangram);
                }
            }
            return partie;
        }
        private static FormeGeometrique [] ToListe(Case [] cases)
        {
            FormeGeometrique[] formes = new FormeGeometrique[cases.Length];
            for (int i = 0; i < cases.Length; i++)
            {
                formes[i] = cases[i].FormeOrigne;
                formes[i].EstBase = false;
            }
            return formes;
        }
        private static FormeGeometrique LoadFormeGeometrique(XmlNode node, Texture2D[] texture)
        {
            String nom;
            int pX, pY;
            float rotation = 0;
            int type = 0;
            FormeGeometrique forme = null;
            bool ignoreRotation = false , ignorePlacement = false;
            nom = node.Name;
            XmlNode position = node.SelectNodes("Position").Item(0);
            pX = Convert.ToInt32( position.Attributes.GetNamedItem("X").Value);
            pY = Convert.ToInt32(position.Attributes.GetNamedItem("Y").Value);
            XmlNode nRotation = node.SelectNodes("Rotation").Item(0);
            rotation = float.Parse(nRotation.InnerText);
            type = Convert.ToInt32(node.SelectNodes("Type").Item(0).InnerText);
            XmlNode option = node.SelectNodes("Option").Item(0);
            ignoreRotation = Convert.ToBoolean(option.Attributes.GetNamedItem("Rotation").Value);
            ignorePlacement = Convert.ToBoolean(option.Attributes.GetNamedItem("Placement").Value);
            switch (nom)
            {
                case "TriangleGrand":
                    forme = new TriangleGrand(texture, new Rectangle(pX, pY, 111, 111));
                    break;
                case "TriangleMoyen":
                    forme = new TriangleMoyen(texture, new Rectangle(pX, pY, 75, 75));
                    break;
                case "TrianglePetit":
                    forme = new TrianglePetit(texture, new Rectangle(pX, pY, 58, 58));
                    break;
                case "Carre":
                    forme = new Carre(texture, new Rectangle(pX, pY, 59, 59));
                    break;
                case "Parallelogramme":
                    forme = new Parallelogramme(texture, new Rectangle(pX, pY, 119, 42));
                    break;
            }
           forme.RotationForme(rotation);
           forme.IgnoreRotation = ignoreRotation;
           forme.IgnorePlacement = ignorePlacement;
           forme.EstBase = type == 1;
           return forme;
        }
        private static void LoadParametre(XmlNode nodePartie, out Partie partie)
        {
            partie = new Partie();
            partie.Nom = nodePartie.Attributes.GetNamedItem("Nom").Value;
            XmlNode option = nodePartie.SelectNodes("Parametre").Item(0);
            partie.ImageFond = option.SelectNodes("ImageFond").Item(0).InnerText;
            partie.Ambiance = option.SelectNodes("Ambiance").Item(0).InnerText;
            partie.EffetDeposé = option.SelectNodes("EffetDepose").Item(0).InnerText;
            partie.EffetTerminé = option.SelectNodes("EffetTermine").Item(0).InnerText;
        }
        private static void SaveParametre(XmlDocument xmldoc, ref XmlElement nodePartie,Partie partie)
        {
            XmlNode partieNom = xmldoc.CreateNode(XmlNodeType.Attribute, "Nom", null);
            partieNom.Value = partie.Nom;
            nodePartie.Attributes.SetNamedItem(partieNom);

            XmlElement parametre = xmldoc.CreateElement("Parametre");

            XmlElement imageFond = xmldoc.CreateElement("ImageFond");
            imageFond.InnerText = partie.ImageFond;
            parametre.AppendChild(imageFond);

            XmlElement Ambiance = xmldoc.CreateElement("Ambiance");
            Ambiance.InnerText = partie.Ambiance;
            parametre.AppendChild(Ambiance);

            XmlElement EffetDepose = xmldoc.CreateElement("EffetDepose");
            EffetDepose.InnerText = partie.EffetDeposé;
            parametre.AppendChild(EffetDepose);
            XmlElement EffetTermine = xmldoc.CreateElement("EffetTermine");
            EffetTermine.InnerText = partie.EffetTerminé;
            parametre.AppendChild(EffetTermine);

            nodePartie.AppendChild(parametre);
        }
        public static void Save(String nom, Partie partie)
        {
            XmlDocument xmldoc = new XmlDocument();
            XmlNode node = xmldoc.CreateNode(XmlNodeType.XmlDeclaration, "", "");
            xmldoc.AppendChild(node);
            XmlElement nPartie = xmldoc.CreateElement("Partie");
            SaveParametre(xmldoc,ref nPartie, partie);
            foreach (Tangram tangram in partie.Tangrams)
                SaveTangram(xmldoc, ref nPartie, tangram);
            xmldoc.AppendChild(nPartie);
            xmldoc.Save(nom);
        }
        private static void SaveTangram(XmlDocument xmldoc, ref XmlElement partie,Tangram tangram)
        {
            XmlElement nTangram = xmldoc.CreateElement("Tangram");
            XmlNode tangramNom = xmldoc.CreateNode(XmlNodeType.Attribute, "Nom", null);
            tangramNom.Value = tangram.Nom;
            nTangram.Attributes.SetNamedItem(tangramNom);
            foreach (FormeGeometrique forme in tangram)
            {
                XmlElement nForme = xmldoc.CreateElement(forme.Name);
                XmlElement position = xmldoc.CreateElement("Position");

                XmlNode poX = xmldoc.CreateNode(XmlNodeType.Attribute, "X", null);
                poX.Value = forme.RectangleDestination.X.ToString();

                XmlNode poY = xmldoc.CreateNode(XmlNodeType.Attribute, "Y", null);
                poY.Value = forme.RectangleDestination.Y.ToString();
                position.Attributes.SetNamedItem(poX);
                position.Attributes.SetNamedItem(poY);

                XmlElement ratation = xmldoc.CreateElement("Rotation");
                ratation.InnerText = forme.Rotation.ToString();

                XmlElement type = xmldoc.CreateElement("Type");
                type.InnerText = "1";

                XmlElement option = xmldoc.CreateElement("Option");

                XmlNode ignoreRotation = xmldoc.CreateNode(XmlNodeType.Attribute, "Rotation", null);
                ignoreRotation.Value = forme.IgnoreRotation.ToString();

                XmlNode ignorePlacement = xmldoc.CreateNode(XmlNodeType.Attribute, "Placement", null);
                ignorePlacement.Value = forme.IgnorePlacement.ToString();

                option.Attributes.SetNamedItem(ignoreRotation);
                option.Attributes.SetNamedItem(ignorePlacement);

                nForme.AppendChild(position);

                nForme.AppendChild(ratation);

                nForme.AppendChild(type);

                nForme.AppendChild(option);

                nTangram.AppendChild(nForme);
            }
            partie.AppendChild(nTangram);
        }
    }
}
